const BaseService = require('./baseService')
const { Op } = require('sequelize')

class UserService extends BaseService {
	constructor(...args) {
		super(...args)
		this.modelName = 'User'
	}
	/**
	 * 根据id 获取用户信息
	 * @param {*} id
	 * @returns
	 */
	async getInfoById(id) {
		return await this.ctx.model[this.modelName].findOne({
			where: {
				id: {
					[Op.eq]: id,
				},
			},
			include: [
				{
					model: this.ctx.model.Role,
					as: 'userRoles',
					attributes: {
						exclude: ['createdAt', 'updatedAt', 'deletedAt'],
					},
				},
			],
		})
	}
	/**
	 * 重置密码
	 * @param {*} obj
	 * @returns
	 */
	async resetPassword(obj) {
		return await this.ctx.model[this.modelName].update(
			{
				password: this.ctx.helper.bcryptData(obj.password),
			},
			{
				where: {
					id: {
						[Op.eq]: obj.id,
					},
				},
			}
		)
	}
	/**
	 * 获取用户列表，
	 * 包括用户信息,用户角色信息,用户的所有评论及其子评论信息，用户所有点赞信息
	 * @param {*} options
	 * @param {*} moduleObj
	 * @param {*} associateModalWhere
	 * @param {*} id
	 * @returns
	 */
	async list(options, moduleObj, associateModalWhere, id = null) {
		let other = {}
		if (associateModalWhere) {
			other['where'] = {
				[associateModalWhere.associateKey]: {
					[Op.eq]: [associateModalWhere.associateVal],
				},
			}
		}
		return await this.Util(options, other, null)
	}
	async getInfoById(id) {
		const IsExisted = await this.IsExisted('User', 'id', id)
		if (!IsExisted) return { flag: false, message: '用戶不存在' }
		let options = {}
		if (id) {
			options['where'] = {
				id: {
					[Op.eq]: id,
				},
			}
		}
		const data = await this.Util(options, null, id)
		if (data) return { flag: true, message: '查询成功', data }
		else return { flag: true, message: '查询失败' }
	}
	/**
	 * 工具函数
	 * @param {*} options where 条件
	 * @param {*} other // 关联模型查询条件 主要是针对角色查询
	 * @param {*} id
	 * @returns
	 */
	async Util(options, other, id) {
		if (id) {
			options['where'] = {
				id: {
					[Op.eq]: id,
				},
			}
		}
		return await this.ctx.model.User.findAndCountAll({
			...options,
			include: [
				{
					model: this.ctx.model.Role,
					as: 'userRoles',
					...other,
					through: {
						attributes: [],
					},
				},
				{
					model: this.ctx.model.Article,
					as: 'userArticles',
				},
				{
					model: this.ctx.model.Comment,
					as: 'userComments',
					include: [
						{
							model: this.ctx.model.Reply,
							as: 'replies',
						},
					],
				},
				{
					model: this.ctx.model.ArticleCollect,
					as: 'userCollects',
					include: [
						{
							model: this.ctx.model.Article,
							as: 'articleDetail',
						},
					],
				},
				{
					model: this.ctx.model.ArticleLike,
					as: 'userLikes',
					include: [
						{
							model: this.ctx.model.Article,
							as: 'articleDetail',
						},
					],
				},
			],
			order: [['userRoles', 'level', 'ASC']],
		})
	}
	/**
	 * 用户点赞功能
	 * @param {*} u_id 点赞用户id
	 * @param {*} art_id 被点赞文献id
	 */
	async thumbsUp(u_id, art_id) {
		return await this.thumbsUpORcollect(u_id, art_id, 'ArticleLike', '点赞')
	}
	/**
	 * 用户收藏功能
	 */
	async collect(u_id, art_id) {
		return await this.thumbsUpORcollect(
			u_id,
			art_id,
			'ArticleCollect',
			'收藏文章'
		)
	}
	/**
	 * 工具函数
	 * @param {*} u_id 点赞用户id
	 * @param {*} art_id 被点赞文献id
	 * @param {*} modelName  模型名称
	 * @param {*} optionName  消息提示中文替换
	 * @returns
	 */
	async thumbsUpORcollect(u_id, art_id, modelName, optionName) {
		const IsExistedU = await this.IsExisted('User', 'id', u_id)
		if (!IsExistedU) if (!u_id) return this.fail({ message: '用户id不存在' })
		const IsExistedA = await this.IsExisted('User', 'id', u_id)
		if (!IsExistedA) if (!art_id) return this.fail({ message: '文章id不存在' })
		// 执行点赞操作
		const isThumbsUp = await this.ctx.model[modelName].findOne({
			where: {
				user_id: {
					[Op.eq]: u_id,
				},
				article_id: {
					[Op.eq]: art_id,
				},
			},
		})
		// 已经点赞过了  删除找到的数据
		if (isThumbsUp) {
			const res = await this.destroyOne(
				modelName,
				'id',
				isThumbsUp?.dataValues?.id
			)
			if (res) {
				return { flag: true, message: `取消${optionName}成功` }
			} else {
				return { flag: false, message: `取消${optionName}失败` }
			}
		} else {
			// 未点赞就 添加一条数据
			const res = this.createOne(modelName, {
				user_id: u_id,
				article_id: art_id,
			})
			if (res) {
				return { flag: true, message: `${optionName}成功` }
			} else {
				return { flag: false, message: `${optionName}失败` }
			}
		}
	}

	/**
	 * 手机账号登录验证手机号是否存在
	 */
	async loginPhone(phone) {
		const data = await this.ctx.model.User.findOne({
			where: {
				phone: {
					[Op.eq]: phone,
				},
			},
		})
		if (data) {
			return { flag: true, data }
		} else {
			return { flag: false, message: `系统不存在手机号为${phone}的用户` }
		}
	}
	/**
	 * 用户删除 同时删除用户的评论 和 回复 以及用户的一切相关数据
	 *
	 */
	async delAll({ ids }) {
		let transaction
		try {
			transaction = await this.ctx.model.transaction()
			for (let i = 0; i < ids.length; i++) {
				const id = ids[i]
				// 文章 id 数据是否存在
				const IsExisted = await this.IsExisted(this.modelName, 'id', id)
				// 只删除一条数据 并且文章不存在
				if (!IsExisted && ids.length === 1)
					return { flag: false, message: '用户不存在' }
				// 删除多条数据 其中出现一条 非法数据 跳过该条数据继续执行删除
				if (!IsExisted && ids.length != 1) continue
				// 执行主表删除
				const delMaster = await this.destroyOne(
					this.modelName,
					'id',
					id,
					transaction
				)
				if (!delMaster) throw Error
				// 删除用户角色表的数据
				const findRoleUser = await this.ctx.model.RoleUser.findAll({
					where: {
						user_id: id,
					},
				})
				if (findRoleUser.length) {
					let RoleUserIds = findRoleUser.map((item) => item.dataValues.user_id)
					const flag = await this.ctx.model.RoleUser.destroy({
						where: {
							user_id: RoleUserIds,
						},
						transaction,
					})
					if (!flag) throw Error
				}
				// 删除该用户评论
				const findArticle = await this.ctx.model.Article.findAll({
					where: {
						user_id: id,
					},
				})
				// 删除该用户存 文章
				if (findArticle.length) {
					let ids = findArticle.map((item) => item.dataValues.id)
					// 执行评论删除 同时删除评论的子评论
					const { flag } = await this.service.articleS.delAll({
						ids,
						transaction,
					})
					if (!flag) throw Error
				}

				// 删除该用户 回复
				const findReply = await this.ctx.model.Reply.findAll({
					where: {
						from_uid: id,
					},
				})

				if (findReply.length) {
					let ReplayIds = findReply.map((item) => item.dataValues.id)
					// 执行评论删除 同时删除评论的子评论
					const flag = await this.ctx.model.Reply.destroy({
						where: {
							id: ReplayIds,
						},
						transaction,
					})
					if (!flag) throw Error
				}

				// 删除该用户 评论
				const findComment = await this.ctx.model.Comment.findAll({
					where: {
						form_uid: id,
					},
				})
				if (findComment.length) {
					let ids = findComment.map((item) => item.dataValues.id)
					// 执行评论删除 同时删除评论的子评论
					const { flag } = await this.service.commentS.delAll({
						ids,
						transaction,
					})
					if (!flag) throw Error
				}
				await transaction.commit()
				return {
					flag: true,
					message: '删除成功',
				}
			}
		} catch (error) {
			await transaction.rollback()
			console.log(error)
			return {
				flag: false,
				message: '删除失败。',
			}
		}
	}
}

module.exports = UserService
